package com.ucweb.pooltest;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.ucweb.pooldemo.R;
import com.ucweb.pooltest.pool.PreciseInactiveObjectsPool;
import com.ucweb.pooltest.pool.PreciseObjectesPool;
import com.ucweb.pooltest.pool.base.IObjectPool;
import com.ucweb.pooltest.util.Setting;

/**
 * 
 * @author chensl@ucweb.com
 * 
 *         下午3:13:33 2014-8-26
 */
public class MainActivity extends ActionBarActivity {
	private final String TAG = "MainActivity";
	private ProgressDialog mProgressDialog;
	private ArrayList<Integer> mNormalCost;
	private ArrayList<Integer> mPoolCost;
	private final int KB = 1 * 1024;
	private final int POOL_SIZE = 50;
	private List<Integer> mList;

	@Override
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		setContentView(R.layout.activity_main);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
				WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		Fragment mMainFragment = new FragmentMain();
		getSupportActionBar().setTitle(getString(R.string.app_name));
		getSupportFragmentManager().beginTransaction()
				.replace(R.id.main_content, mMainFragment).commit();
		Setting.getInstance(getApplicationContext());
		mNormalCost = new ArrayList<Integer>();
		mPoolCost = new ArrayList<Integer>();
		mList = new ArrayList<Integer>();
		mList.add(10 * KB);
		mList.add(100 * KB);
		mList.add(1024 * KB);
		initDialog();
	}

	private void initDialog() {
		mProgressDialog = new ProgressDialog(MainActivity.this);
		mProgressDialog.setTitle(getString(R.string.dialog_title_running_str));
		mProgressDialog.setMessage(getString(R.string.writting_str));
		mProgressDialog.setCancelable(false);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_item_setting_id:
			Intent intent = new Intent(this, SettingActivity.class);
			startActivity(intent);
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	class FragmentMain extends Fragment implements OnItemClickListener {
		private View view;
		private ListView mListView;
		private int loaction;

		@Override
		public View onCreateView(LayoutInflater inflater,
				@Nullable ViewGroup container,
				@Nullable Bundle savedInstanceState) {
			view = inflater.inflate(R.layout.fragment_main, container, false);
			mListView = (ListView) view.findViewById(R.id.main_item_list_id);
			String[] mainItems = getResources().getStringArray(
					R.array.main_item_strs);
			ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
					getApplicationContext(),
					android.R.layout.simple_list_item_1, mainItems);
			mListView.setAdapter(arrayAdapter);
			mListView.setOnItemClickListener(this);
			return view;
		}

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			mProgressDialog.show();
			switch (position) {
			case 0:
				new Thread() {
					public void run() {
						normalTest();
						PreciseObjectesPoolTest();
						runOnUiThread(new Thread() {
							public void run() {
								mProgressDialog.dismiss();
								Intent intent = new Intent(MainActivity.this,
										ResultActivity.class);
								intent.putExtra(ResultActivity.KEY_NORMAL_COST,
										mNormalCost);
								intent.putExtra(ResultActivity.KEY_POOL_COST,
										mPoolCost);
								startActivity(intent);
							};
						});
					};
				}.start();
				break;
			case 1:
				new Thread() {
					public void run() {
						normalTest();
						PreciseInactiveObjectesPoolTest();
						runOnUiThread(new Thread() {
							public void run() {
								mProgressDialog.dismiss();
								Intent intent = new Intent(MainActivity.this,
										ResultActivity.class);
								intent.putIntegerArrayListExtra(
										ResultActivity.KEY_NORMAL_COST,
										mNormalCost);
								intent.putIntegerArrayListExtra(
										ResultActivity.KEY_POOL_COST, mPoolCost);
								startActivity(intent);
							};
						});
					};
				}.start();
				break;
			default:
				throw new IllegalArgumentException();
			}
		}

		private void normalTest() {
			long now;
			mNormalCost.clear();
			Random random = new Random();
			for (int i = 0; i < mList.size(); i++) {
				now = System.currentTimeMillis();
				for (int index = 0; index < Setting.getInstance()
						.getAllocateCount(); index++) {
					byte[] b = new byte[mList.get(i)];
					if (random.nextBoolean()) {
						// 为了减少误差，这里也判断一下吧
						b = null;
					}
				}
				mNormalCost.add(((int) (System.currentTimeMillis() - now)));
			}
			Log.d(TAG, "普通新建" + Setting.getInstance().getAllocateCount()
					+ "次，耗时：" + mNormalCost);
		}

		private void PreciseObjectesPoolTest() {
			IObjectPool<byte[]> pool = null;
			mPoolCost.clear();
			Random random = new Random();
			long now;
			for (loaction = 0; loaction < mList.size(); loaction++) {
				pool = new PreciseObjectesPool<byte[]>() {
					@Override
					public byte[] createObject() {
						return new byte[mList.get(loaction)];
					}
				};
				now = System.currentTimeMillis();
				pool.createPool(POOL_SIZE);
				for (int index = 0; index < Setting.getInstance()
						.getAllocateCount(); index++) {
					byte[] b = pool.allocate();
					if (random.nextBoolean()) {
						pool.deallocate(b);
					}
				}
				mPoolCost.add((int) (System.currentTimeMillis() - now));
				pool.cleanUp();
				pool.release();
			}
			Log.d(TAG, "总上限对象池分配" + Setting.getInstance().getAllocateCount()
					+ "次，耗时：" + mPoolCost);
			Log.d(TAG, "当前对象池状态:" + pool.toString());
		}

		private void PreciseInactiveObjectesPoolTest() {
			IObjectPool<byte[]> pool = null;
			mPoolCost.clear();
			Random random = new Random();
			long now;
			for (loaction = 0; loaction < mList.size(); loaction++) {
				pool = new PreciseInactiveObjectsPool<byte[]>() {
					@Override
					public byte[] createObject() {
						return new byte[mList.get(loaction)];
					}
				};
				now = System.currentTimeMillis();
				pool.createPool(POOL_SIZE);
				for (int index = 0; index < Setting.getInstance()
						.getAllocateCount(); index++) {
					byte[] b = pool.allocate();
					if (random.nextBoolean()) {
						pool.deallocate(b);
					}
				}
				mPoolCost.add((int) (System.currentTimeMillis() - now));
				pool.cleanUp();
				pool.release();
			}
			Log.d(TAG, "总上限对象池分配" + Setting.getInstance().getAllocateCount()
					+ "次，耗时：" + mPoolCost);
			Log.d(TAG, "当前对象池状态:" + pool.toString());
		}

	}

}
